﻿using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.Ink;
using ICSharpCode.SharpZipLib.Zip;
using Modele;
using vue;
using System.Drawing;
using System.IO;


namespace Sauvegarde
{

    /**
    * @author PAN
    * @date Juin 2010
    * @brief La classe writer1 permet la sauvegarde d'un projet PAN
    */
    class writer1
    {

        Modele.Modele m;


        /** 
         * writer1(Modele.Modele mod)
         * 
         * @brief : Constructeur
         * @param : Modele.Modele mod le modele avec lequel on instancie le paramètre m de la classe writer1
         */
        public writer1(Modele.Modele mod)
        {
            m = mod;
        }


        /** 
         * ecrireDansPan(ZipFile zip,String fichier)
         * 
         * @brief : permet d'ajouter un fichier à l'archive zip
         * @param : ZipFile zip l'archive à laquelle ajouter le fichier
         * @param : string fichier l'adresse et le nom du fichier à ajouter dans l'archive
         * @return void
         */
        static void ecrireDansPan(ZipFile zip,String fichier)
        {
            //initialize the file so that it can accept updates
            zip.BeginUpdate();

            //add the file to the zip file
            zip.Add(fichier);

            //commit the update once we are done
            zip.CommitUpdate();
            //close the file
            zip.Close();
        }

        /** 
        * ecrireUPX(String cheminAbs)
        * 
        * @brief : fonction principale de la sauvegarde (entre autres crée un fichier UPX)
        * @param : string cheminAbs le chemin absolu du fichier UPX (chemin + nom du fichier + extension)
        * @return : void
        */
        public void ecrireUPX(String cheminAbs)
        {

            String chemin = ManipulationChaine.extension(cheminAbs);
            String nomFichier = ManipulationChaine.fichierPan(cheminAbs);
            String nomProjet = ManipulationChaine.nomFichier(cheminAbs);

            Directory.CreateDirectory(chemin + "\\" + nomProjet + "PAN");

            //create our zip file
            //ZipFile z = ZipFile.Create(cheminAbs);

            
            // Create a new file

            String nom_upx = chemin + "\\" + nomProjet + "PAN" + "\\" + nomFichier;

            //String nom_upx = cheminAbs;

            XmlTextWriter textWriter = new XmlTextWriter(nom_upx, null);

            // Opens the document

            textWriter.WriteStartDocument();

            // Write comments

            textWriter.WriteComment("Document XML de sauvegarde de projet PAN au format UPX");

            textWriter.WriteComment( nomFichier+ "dans le projet" + nomProjet);

            //élément racine
            textWriter.WriteStartElement("sauvegarde");

            ProjetBlocNote p = m.getProjet();
            Bitmap imageFond = p.getImagePageCourant();

            //enregistrement de l'image de fond
            if (imageFond != null)
            {
                String url_image = nomProjet+"_image_Fond.bmp";

                imageFond.Save(chemin + "\\" + nomProjet + "PAN" + "\\" + url_image);
                //imageFond.Save(chemin + "\\" + url_image);
                //z.BeginUpdate();
                //z.Add(url_image);
                //z.CommitUpdate();
                //System.IO.File.Delete(chemin + "\\" + url_image);

                textWriter.WriteStartElement("image");
                textWriter.WriteAttributeString("url_image", url_image);
                textWriter.WriteEndElement();
            }


            //sauvegarde de la liste des auteurs sur le projet
            IEnumerator auth = p.getAuthors().GetEnumerator();
            int au = 0;
            textWriter.WriteStartElement("auteursProjet");
            auth.MoveNext();
            while (auth.MoveNext())
            {
                textWriter.WriteAttributeString("nom"+au,auth.Current.ToString());
                au++;
            }
            textWriter.WriteEndElement();

            //sauvegarde de la liste des mots clés
            IEnumerator key = p.getKeyWords().GetEnumerator();
            int ke = 0;
            textWriter.WriteStartElement("mots_cles");
            key.MoveNext();
            while (key.MoveNext())
            {
                textWriter.WriteAttributeString("nom" + ke, key.Current.ToString());
                ke++;
            }
            textWriter.WriteEndElement();

            //sauvegarde de la liste des images de balises
            IEnumerator bibImage = p.getBibImages().GetEnumerator();
            int bi = 0;
            textWriter.WriteStartElement("bibliothèqueImages");
            while (bibImage.MoveNext())
            {
                String nomImageBal = nomProjet + "Imgbalise" + bi + ".bmp";
                textWriter.WriteAttributeString("url_image_balise"+bi,nomImageBal);
                Bitmap imageBalise = (Bitmap)bibImage.Current;

                imageBalise.Save(chemin + "\\" + nomProjet + "PAN" + "\\" + nomImageBal);
                //imageBalise.Save("" + chemin + "\\" + nomImageBal);
                bi++;
            }
            textWriter.WriteEndElement();
            

            //sauvegarde de la liste des balises
            IEnumerator bibBalise = p.getBibBal().GetEnumerator();
            int bb = 0;
            textWriter.WriteStartElement("bibliothèqueBalises");
            int nbb = p.getBibBal().Count-1;
            textWriter.WriteAttributeString("nombre", nbb.ToString());
            bibBalise.MoveNext();
            while (bibBalise.MoveNext())
            {
                textWriter.WriteStartElement("bal"+bb);
                String nomBal = nomProjet + "balise" + bb + ".bmp";
                textWriter.WriteAttributeString("url_balise",nomBal);
                Bitmap imageBa = ((Balise)bibBalise.Current).getIcone();
                imageBa.Save(chemin + "\\" + nomProjet + "PAN" + "\\" + nomBal);

                //imageBa.Save("" + chemin + "\\" + nomBal);

                String sig = ((Balise)bibBalise.Current).getSemantique().getSignification();
                String prenAut = ((Balise)bibBalise.Current).getPrenom();
                String nomAut = ((Balise)bibBalise.Current).getNom();
                textWriter.WriteAttributeString("signification",sig);
                textWriter.WriteAttributeString("prenom",prenAut);
                textWriter.WriteAttributeString("nom",nomAut);
                textWriter.WriteEndElement();
                bb++;
            }
            textWriter.WriteEndElement();
            

            //nombre de pages (peu pertinent maintenant vu que pas de PDF)
            textWriter.WriteStartElement("nbPages");
            textWriter.WriteAttributeString("nb", "" + m.getProjet().getNbrPage());
            textWriter.WriteEndElement();

            IEnumerator e = m.getProjet().getBlocCourant().GetEnumerator();
              int i = 1;//ATTENTION il faut demarrer à 0, la couche 0 correspond au document (ne pas oublier d'incrémenter lorsque l'on gèrera l'image) 
              int j = 0;
              //int k = 0;
            while (e.MoveNext())
            {
                Couche couche1 = (Couche)e.Current;

                    //niveau couche
                    textWriter.WriteStartElement("hlevel");
                    textWriter.WriteAttributeString("level","couche");
                    textWriter.WriteAttributeString("idcouche", "" + i);
                if (couche1.estVisible())
                    {
                        textWriter.WriteAttributeString("visible", "oui");
                    }
                    else
                    {
                        textWriter.WriteAttributeString("visible", "non");
                    }
                    textWriter.WriteAttributeString("nom_couche",couche1.getNom());

                    i++;

                    foreach (Calque calque1 in couche1.getCouche())
                    {

                        /*
                        //niveau page
                        if ((obj.GetType()).Equals(Page))
                        {
                            textWriter.WriteStartElement("hlevel");
                            textWriter.WriteAttributeString("level", "page");
                            textWriter.WriteAttributeString("id", "page" + i);
                            i++;
                            }*/

                        //niveau calque

                        textWriter.WriteStartElement("hlevel");
                        textWriter.WriteAttributeString("level", "calque");
                        textWriter.WriteAttributeString("idcalque", "" + j);


                        String nom_calque = nomProjet+"_sauvegarde_calque" + j + ".inkml";

                        textWriter.WriteAttributeString("url_calque", "" + nom_calque);

                        //sauvegarde de l'attribut encre du calque sous le nom du projet suivi du numéro du calque
                        
                        EnregistrementPAN enre = new EnregistrementPAN();
                        enre.enregistrer(calque1.encre, "" + chemin + "\\" + nomProjet + "PAN" + "\\" + nom_calque);

                        //enre.enregistrer(calque1.encre,"" + chemin + "\\" + nom_calque);
                        //ecrireDansPan(z,nom_calque);

                        //initialize the file so that it can accept updates
                        //z.BeginUpdate();

                        //add the file to the zip file
                        //z.Add(nom_calque);

                        //commit the update once we are done
                        //z.CommitUpdate();
                        //il ne faut pas fermer l'archive tant que l'on a pas terminer les ajouts

                        //System.IO.File.Delete(chemin + "\\" + nom_calque);

                        j++;


                        //int m = 0;
                        int n = 0;
                        int o = 0;

                        //énumérateur sur annotations_map pour les balises

                        IEnumerator  ano = calque1.getAnnotations().GetEnumerator();
                        while (ano.MoveNext())
                        {
                            AnnotationPAN anno = (AnnotationPAN)ano.Current;

                                //ouverture niveau balise
                                textWriter.WriteStartElement("hlevel");
                                textWriter.WriteAttributeString("level", "balise");
                                textWriter.WriteAttributeString("idbalise", "" + n);

                                //sauvegarde de l'icone de la balise
                                String url_balise = nomProjet+"_icone_balise" + n + ".bmp";
                                textWriter.WriteAttributeString("url_icone_balise",url_balise);
                                Bitmap iconeBalise = ((Balise)anno).getIcone();

                                iconeBalise.Save("" + chemin + "\\" + nomProjet + "PAN" + "\\" + url_balise);
                                //iconeBalise.Save(""+chemin+"\\"+url_balise);
                                //z.BeginUpdate();
                                //z.Add(url_balise);
                                //z.CommitUpdate();
                                //System.IO.File.Delete(chemin + "\\" + url_balise);


                                //ecrireDansPan(z, url_balise);

                                
                                
                                //position
                                textWriter.WriteStartElement("position");
                                textWriter.WriteAttributeString("positionX", "" + anno.getPosition().getPosX());
                                textWriter.WriteAttributeString("positionY", "" + anno.getPosition().getPosY());
                                textWriter.WriteEndElement();

                                //auteur
                                textWriter.WriteStartElement("auteur");
                                textWriter.WriteAttributeString("prenom", "" + anno.getSemantique().getPrenom());
                                textWriter.WriteAttributeString("nom", "" + anno.getSemantique().getNom());
                                textWriter.WriteEndElement();


                                //sémantique
                                textWriter.WriteStartElement("label");
                                textWriter.WriteStartElement("alternate");

                                String sann = anno.getSemantique().getSignification();
                                textWriter.WriteString("" + sann);
                                
                                textWriter.WriteEndElement();
                                textWriter.WriteEndElement();
                                
                                
                                n++;

                                //fermeture niveau balise
                                textWriter.WriteEndElement();

                        }//fermeture du while

                        //énumérateur sur textes l'arrayList de texte
                        IEnumerator en = calque1.getTextes().GetEnumerator();

                        while(en.MoveNext()) 
                        {
                            AnnotationPAN anno = (AnnotationPAN)en.Current;

                                    //ouverture niveau texte
                                    textWriter.WriteStartElement("hlevel");
                                    textWriter.WriteAttributeString("level", "texte");
                                    textWriter.WriteAttributeString("idtexte", "" + o);
                                    String tex = ((Texte)anno).getIcone();
                                    textWriter.WriteAttributeString("att_texte", tex);

                                    //police
                                    textWriter.WriteStartElement("police_texte");
                                    textWriter.WriteAttributeString("police",((Texte)anno).getPolice().Name);
                                    textWriter.WriteAttributeString("taille", ((Texte)anno).getPolice().Size.ToString());
                                    textWriter.WriteEndElement();

                                    //position
                                    textWriter.WriteStartElement("position");
                                    textWriter.WriteAttributeString("positionX", "" + anno.getPosition().getPosX());
                                    textWriter.WriteAttributeString("positionY", "" + anno.getPosition().getPosY());
                                    textWriter.WriteEndElement();

                                    /*
                                    //auteur
                                    textWriter.WriteStartElement("auteur");
                                    Semantique semant = anno.getSemantique();
                                    String pren = anno.getSemantique().getPrenom();
                                    textWriter.WriteAttributeString("prenom", "" + anno.getSemantique().getPrenom());
                                    textWriter.WriteAttributeString("nom", "" + anno.getSemantique().getNom());
                                    textWriter.WriteEndElement();
                            
                                   
                                    //sémantique
                                    textWriter.WriteStartElement("label");
                                    textWriter.WriteStartElement("alternate");
                                    String sann = anno.getSemantique().getSignification();
                                    textWriter.WriteString("" + sann);
                                    textWriter.WriteEndElement();
                                    textWriter.WriteEndElement();
                                    */

                                    o++;

                                    //fermeture niveau texte
                                    textWriter.WriteEndElement();
 
                        }//fermeture du while sur l'énurateur de textes

                        //fermeture niveau calque
                        textWriter.WriteEndElement();

                    }//fermeture du foreach sur les calques

                    //fermeture niveau couche
                    textWriter.WriteEndElement();

            }//fermeture du while sur les couches

            //fin élément racine
            textWriter.WriteEndElement();

            textWriter.Close();

            //ecrireDansPan(z, nom_upx);
            //TODO effacer le fichier après l'avoir ajouter à l'archive

            //initialize the file so that it can accept updates
            //z.BeginUpdate();

            //add the file to the zip file
            //z.Add(nom_upx);

            //commit the update once we are done
            //z.CommitUpdate();

            //close the file
            //z.Close();

            //TODO a voir le fichier ne se crée pas correctement si on le supprime là
            //System.IO.File.Delete(chemin + "\\" + nom_upx);

        }
    }
}